package com.smforj.ssm.modules.sys.util;

import java.text.ParseException;
import java.util.Date;

import org.apache.commons.lang3.time.DateUtils;

import com.smforj.ssm.frame.core.constant.Const;
import com.smforj.ssm.frame.core.constant.Separator;
import com.smforj.ssm.frame.core.utils.StringEx;
import com.smforj.ssm.modules.lib.domain.CheckInResponse;
import com.smforj.ssm.modules.lib.domain.CheckOutResponse;
import com.smforj.ssm.modules.lib.domain.ItemResponse;
import com.smforj.ssm.modules.lib.domain.PatronResponse;
import com.smforj.ssm.util.DateFormat;

/***
 * sip2 send message command
 * 
 * @author Haijun Gao 
 * @date 2016-8-4 下午12:12:00
 * @desp http://www.cnblogs.com/saga5998/
 * @email 573107773@qq.com
 */
public class SIP2MsgQingyang implements ISip2Msg { 
	
	private static final String CHECKSUM = "AY0AZF5D9";
	/***
	 * 仅适用于个别时间
	 */
	private static final String FORMATDATE = "yyyy-MM-dd";
	/**
	 * 机构代码
	 */
	private static final String INSTID = "107"; 
/*      private static int GetChecksum(String szCMD)
      {
          try
          {
              int num1 = 0;
              int num2 = szCMD.length();
              String text2 = szCMD;
              for (int num5 = 0; num5 < text2.length(); num5++)
              {
            	  int num3 = text2[num5];
                  num1 = (int)(num1 + num3);
              }
              num1 = (int)(~num1 + 1);
              String text1 = num1.ToString("X").PadLeft(4, '0');
              szCMD = szCMD + text1;
              // szCMD = szCMD + Environment.NewLine;
          }
          catch (Exception ex)
          {
              return 0;
          }
          return 1;
      } */ 
	
    /***
     *  SC->ACS 登录
     * @param szUser 用户code
     * @param szUserPWD 密码
	 * @return
	 * @date 2016-8-4 下午3:15:24
	 */
    public String loginMsg(String szUser, String szUserPWD)
    { 
        return loginMsg(szUser,szUserPWD,""); 
    } 
	  /***
	   *  SC->ACS 登录
	   * @param szUser 用户code
	   * @param szUserPWD 密码
	   * @param scLocation sc Location
	   * @return sip2消息字符串
	   * @date 2016-8-4 上午10:06:24
	   */
	  public  String loginMsg(String szUser, String szUserPWD,String scLocation)
	  {
		  StringBuffer sb = new StringBuffer();
		  sb.append("93");
		  sb.append("00");
		  sb.append("CN");
		  sb.append(szUser);
		  sb.append(Separator.SVERTICAL);
		  sb.append("CO");
		  sb.append(szUserPWD);
		  sb.append(Separator.SVERTICAL);
		  sb.append("CP");
		  sb.append(scLocation);
		  sb.append(Separator.SVERTICAL);
		  sb.append(CHECKSUM); 
	      return sb.toString(); 
	  } 

  
      /***
       *  SC->ACS借阅者信息
       * @param readerCardId 借阅者卡号
       * @param readerPWD 借阅者密码
       * @return 发送字符串
       * @date 2016-8-4 下午3:01:25
       */
      public  String readerInfoMsg(String readerCardId, String readerPWD)
      { 
          return readerInfoMsg(readerCardId,"107",readerPWD); 
      } 
      
      /***
       * SC->ACS借阅者信息
       * @param readerCardId 借阅者卡号
       * @param institutionId 机构标识
       * @param readerPWD 借阅者密码
       * @return 发送字符串
       * @date 2016-8-4 下午3:22:42
       */
      public  String readerInfoMsg(String readerCardId, String institutionId,String readerPWD)
      {

          StringBuffer sb = new StringBuffer();
          sb.append("63"); // 63号命令
          sb.append("000"); // 语言
          sb.append(DateFormat.dateToString("yyyyMMdd    HHmmss")); //执行时间，注意有4个空格
          sb.append("Y     "); // 占位符，第0位表示"hold items"summary
          sb.append("AO"); //107
          sb.append(institutionId);// SC机构标识044120
          sb.append(Separator.SVERTICAL);
          sb.append("AA" + readerCardId); // 借阅者卡号
          sb.append(Separator.SVERTICAL);
          sb.append("AD" + readerPWD); // 借阅者密码
          sb.append(Separator.SVERTICAL);
          sb.append(CHECKSUM); // 准备校验码 
          return sb.toString(); 
      }  
      /***
       *  SC->ACS图书信息
       * @param bookid 图书条码或RFID
       * @return
       * @date 2016-8-4 下午3:28:18
       */
      public  String bookInfoMsg(String bookid)
      { 
          return bookInfoMsg("css",bookid,"");
      } 
      
      /***
       * SC->ACS图书信息
       * @param institutionId 机构代码
       * @param bookid 图书标识 一般是Barcode
       * @param tPwd 设备密码
       * @return
       * @date 2016-8-4 下午3:26:36
       */
      public  String bookInfoMsg(String institutionId,String bookid,String tPwd)
      {
          StringBuilder sb = new StringBuilder();
          sb.append("17"); // 17号命令
          sb.append(DateFormat.dateToString("yyyyMMdd    HHmmss")); //执行时间，注意有4个空格
          sb.append("AO"); // SC机构标识044120
          sb.append(institutionId);
          sb.append(Separator.SVERTICAL);
          sb.append("AB" + bookid.toUpperCase().trim()); // 图书id（条码）
          sb.append(Separator.SVERTICAL);
          sb.append("AC"); // 终端密码，此处不提供
          sb.append(tPwd);
          sb.append(Separator.SVERTICAL);
          sb.append(CHECKSUM); // 准备校验码 
          return sb.toString().trim();
      }  
      /***
       * SC->ACS还书命令
       * @param bookid 条码或RFID
       * @return ACS->SC返回的命令
       * @date 2016-8-4 下午3:31:41
       */
      public  String returnMsg(String bookid)
      {
          StringBuilder sb = new StringBuilder();
          sb.append("09"); // 09号命令
          sb.append("N"); // 执行
          Date date = new Date(); 
          String format = "yyyyMMdd    HHmmss";
          sb.append(DateFormat.dateToString(date, format)); //执行时间，注意有4个空格
          sb.append(DateFormat.dateToString(date, format)); //执行时间，注意有4个空格
          sb.append("AP"); // 还书地点，未指定
          sb.append(Separator.SVERTICAL);
          sb.append("AO"); // SC机构标识044120
          sb.append(INSTID);
          sb.append(Separator.SVERTICAL);
          sb.append("AB" + bookid.trim()); // 图书id（条码）
          sb.append(Separator.SVERTICAL);
          sb.append("AC"); // 终端密码，此处不提供
          sb.append(Separator.SVERTICAL);
          sb.append(CHECKSUM); // 准备校验码 
          return sb.toString().trim();
      }  
      /***
       * SC->ACS借书命令
       * @param readerCardId 借阅者证件号
       * @param readerCardPWD 证件密码（非必须）
       * @param bookid 图书id（条码）  
       * @return
       * @date 2016-8-4 下午3:34:39
       */
      public  String borrowMsg(String readerCardId,String readerCardPWD, String bookid)
      {
    	  return borrowMsg(readerCardId, readerCardPWD, bookid,"");
      }
      
      /***
       * SC->ACS借书命令
       * @param readerCardId 借阅者证件号
       * @param bookid 图书id（条码）
       * @param termPWD 终端密码
       * @param readerCardPWD 证件密码（非必须）
       * @return
       * @date 2016-8-4 下午3:34:39
       */
      public  String borrowMsg(String readerCardId,String readerCardPWD, String bookid, String termPWD)
      {
          StringBuilder sb = new StringBuilder();
          sb.append("11"); // 11号命令
          sb.append("Y"); // Y：该书可以续借；N：该书不能续借
          sb.append("N"); 
          Date date = new Date(); 
          String format = "yyyyMMdd    HHmmss";
          sb.append(DateFormat.dateToString(date, format)); //执行时间，注意有4个空格
          sb.append(DateFormat.dateToString(date, format)); //执行时间，注意有4个空格
          sb.append("AO"); // SC机构标识044120
          sb.append(INSTID);
          sb.append(Separator.SVERTICAL);
          sb.append("AA" + readerCardId.trim()); // 借阅者证件号
          sb.append(Separator.SVERTICAL);
          sb.append("AB" + bookid.trim()); // 图书id（条码）
          sb.append(Separator.SVERTICAL);
          sb.append("AC" + termPWD.trim()); // 终端密码，此处不提供
          sb.append(Separator.SVERTICAL);
          sb.append("AD" + readerCardPWD.trim()); // 证件密码（非必须）
          sb.append(Separator.SVERTICAL);
          sb.append(CHECKSUM); // 准备校验码
          return sb.toString().trim(); 
      }  

      /***
       * SC->ACS续借命令
       * @param readerCardId 借阅者证件号
       * @param readerCardPWD 证件密码（非必须）
       * @param bookId 图书id（条码）
       * @return
       * @date 2016-8-4 下午12:11:04
       */
      public  String renewMsg(String readerCardId, String readerCardPWD, String bookId)
      { 
          StringBuilder sb = new StringBuilder();
          sb.append("29");
          sb.append("Y");
          sb.append("N");  
          String format = "yyyyMMdd    HHmmss";//执行时间，注意有4个空格 
          sb.append(DateFormat.dateToString(format));//transaction date
          sb.append(DateFormat.dateToString(format));//nb due date
          sb.append("AO");
          sb.append(INSTID);
          sb.append("|");
          sb.append("AA");
          sb.append((null == readerCardId)? "" : readerCardId); 
          sb.append(Separator.SVERTICAL);
          sb.append("AD");
          sb.append(null == readerCardPWD ? "" : readerCardPWD); 
          sb.append(Separator.SVERTICAL);
          sb.append("AB");
          sb.append(null == bookId ? "" :bookId); 
          sb.append(Separator.SVERTICAL);
          sb.append("AC|");
          sb.append("CH|");
          sb.append("BOY");
          sb.append("AY3AZ"); 
          return sb.toString();
      }  
      /***
       * 根据字段返回内容
       * @param str 分割的信息<
       * @param field 字段，如“AA”
       * @return 字段后面的内容
       * @date 2016-8-4 下午3:50:21
       */
      public  String getContentByField(String[] stra, String field)
      {
    	  return getContentByField(stra,field,2);
      } 
      /***
       * 根据字段返回内容
       * @param str 分割的信息<
       * @param field 字段，如“AA”
       * @param length 截取长度
       * @return 字段后面的内容
       * @date 2016-8-4 下午3:50:21
       */
      public  String getContentByField(String[] stra, String field,int length)
      {
          for(String s : stra)
          {
              if (s.startsWith(field.toUpperCase()))
                  return s.substring(length);
          }
          return "";
      }
      
      /***
       * 第一个特殊处理
       * @param stra
       * @return
       * @date 2016-8-4 下午6:05:12
       */
      public  String getFirstField(String[] stra,String field)
      {
    	  if(stra == null || stra.length < 1)
    		  return "";
    	  String str = stra[0];
    	  return str.substring(str.indexOf(field)+field.length());
      }

      /***
       *  分隔多符号字符串
       * @param stra
       * @param field
       * @return
       * @date 2016-8-4 下午3:53:26
       */
      public  String[] GetMultiContentByField(String[] stra, String field)
      {
          String[] rstra = null;
          for(String s : stra)
          {
              if (s.startsWith(field))
              {
                  rstra = s.substring(2).split(",");
                  break;
              }
          }
          return rstra;
      } 

      /// <summary>
      /// 解析登陆返回信息
      /// </summary>
      /// <param name="loginResponse"></param>
      /// <param name="readerInfo"></param>
      /// <returns></returns>
      public  Boolean login(String loginResponse)
      {
          if (StringEx.isExEmpty(loginResponse)) return false;
          return loginResponse.substring(2, 3).toUpperCase() == "1" ? true : false; 
      }  
      /***
       * 解析借阅者信息
       * @param readerInfoMsg 返回的借阅者SIP2信息
       * @return Result ERROR 借阅者对象 或 null
       * @date 2016-8-4 下午4:09:19
       */
      public  PatronResponse parseReaderInfo(String readerInfoMsg)
      {
    	  
    	  PatronResponse readerInfo = new PatronResponse(); 
          // 示例:
          // String returnMsg = "64              000201012210000101630000000000003000700000000AOuestc|AA200921060447|
    	  //                                     AE宋毅|BZ0002|CA0051|CB0020|BLY|CQY|BV1.30|CC2.00|AY3AZDC4E"; 
          if (!StringEx.isExEmpty(readerInfoMsg) && readerInfoMsg.startsWith("64"))
          { 
              String[] s = readerInfoMsg.split(Const.SVERTICAL);   
              // 必有字段
              readerInfo.setCampusCardNum(getContentByField(s, "AA"));  // 卡号AA 
              readerInfo.setReaderName(getContentByField(s, "AE"));  // 姓名AE
              readerInfo.setHoldItemsCount(readerInfoMsg.substring(37, 41));
              readerInfo.setCountOverDue(readerInfoMsg.substring(41, 45));
              readerInfo.setCountCharged(readerInfoMsg.substring(45, 49));
              readerInfo.setCountFine(readerInfoMsg.substring(49, 53));
              readerInfo.setCountRecall(readerInfoMsg.substring(53, 57));
              //持有图书
              readerInfo.setHoldItemsLimit(getContentByField(s, "BZ"));

              // 可选字段  
              readerInfo.setHoldBooks(GetMultiContentByField(s, "AS")); // 在借图书名称集合   
              readerInfo.setOverdueBooks(GetMultiContentByField(s, "AT")); // 超期图书名称集合  
              readerInfo.setChargedBooks(GetMultiContentByField(s, "AU")); // 产生费用图书名称集合 
              readerInfo.setCountTotal(getContentByField(s, "CB"));  //最大借阅数 
              readerInfo.setReaderFee(Double.parseDouble(getContentByField(s, "BV"))); // 欠费金额 
              readerInfo.setFeeMax(Double.parseDouble(getContentByField(s, "CC"))); // 最大罚金 
              readerInfo.setIsReaderCardIdValid(getContentByField(s, "BL")); 
              readerInfo.setIsReaderPWDValid(getContentByField(s, "CQ")); 
          }else
          {
        	  readerInfo.setStatus(0);
        	  readerInfo.setMessage("返回信息为空或不正确："+readerInfoMsg);
          }
          return readerInfo;
      }   
      /***
       * 转换图书对象信息
       * @param bookInfoMsg 消息字符串
       * @return 转换后对象 status 不在该对象中体现意义
       * @date 2016-8-4 下午4:37:54
       */
      public  ItemResponse parseBookInfo(String bookInfoMsg)
      {
    	  ItemResponse bookInfo = new ItemResponse(); 
          if (!StringEx.isExEmpty(bookInfoMsg) && bookInfoMsg.startsWith("18"))
          {
              // 示例:
              // 1803020420160418    112235ABB00020|AJ法语.第一册|BG马晓宏，柳利编|BV1490|CK001|AP典藏室1|CH中文图书|
              //                                    CT外语教学与研究出版社|CS00|查询完毕！|AY1AZDC88
              // 1803020420160418    112225ABB000202|AJ|CS00|查询完毕！|AY1AZF142 
              String[] s = bookInfoMsg.split(Const.SVERTICAL); 
              bookInfo.setStatus(1);//
              // 必有字段  
              bookInfo.setBookId(getFirstField(s, "AB")); // 图书条码或RFID号 
              bookInfo.setBookName(getContentByField(s, "AJ")); // 图书题名   
              //bookInfo.b_bookStatus = "";//状态查询是无状态的
              //可靠字段 
              bookInfo.setFee(getContentByField(s, "BV"));//fee amount
              bookInfo.setItemType(getContentByField(s, "CK"));  // 类型（没有做细化）
              bookInfo.setLocation(getContentByField(s, "AP"));  // 馆藏地
              bookInfo.setProps(getContentByField(s, "CH"));  // 图书属性
              bookInfo.setPublisher(getContentByField(s, "CT")); //出版社   
              bookInfo.setCallNum(getContentByField(s, "AQ")); // 索书号
              bookInfo.setEnd(getContentByField(s, "AY"));//结束符号 
          }else
          {
         	  bookInfo.setStatus(0);
        	  bookInfo.setMessage("返回信息为空或不正确："+bookInfoMsg);
          }
          return bookInfo;
      }  
      /***
       * 解析还书 图书信息 
       * @param bookInfoMsg 返回的图书SIP2信息
       * @return 转换的图书对象
       * @date 2016-8-4 下午4:47:25
       */
      public  CheckInResponse parseReturn(String bookInfoMsg)
      { 
          // 示例:
          // 101YNN20160418    114720AO00|ABB00084|AQ典藏室1|AJ证据法学|AF还书成功|AG还书成功|AY1AZE9A9
          // 100NNY20160418    114248AO00|ABB00100|AQ典藏室1|AJ仲裁法学|AF本书没有外借|AG本书没有外借|AY1AZEA24
          // 100NN?20160418    114853AO00|ABB000841|AQ|AF本图书不存在|AG本图书不存在|AY1AZEE58 
    	  CheckInResponse bookInfo = new CheckInResponse(); 
          if (!StringEx.isExEmpty(bookInfoMsg) && bookInfoMsg.startsWith("10"))
          {  
              String[] s = bookInfoMsg.split(Const.SVERTICAL);  
              //执行状态 0 失败 1 成功
              int status = Integer.parseInt(bookInfoMsg.substring(2, 3));
              bookInfo.setStatus(status); 
              // 必有字段  
              bookInfo.setBookId(getFirstField(s, "AB")); // 图书条码或RFID号
              bookInfo.setBookName(getContentByField(s, "AJ")); // 图书题名   
              bookInfo.setLocation(getContentByField(s, "AQ")); // 馆藏地
              bookInfo.setMessage(getContentByField(s, "AF")); //信息 
              if(StringEx.isExEmpty(bookInfo.getMessage()))
            	  bookInfo.setMessage(getContentByField(s, "AG")); //信息 
              bookInfo.setEnd(getContentByField(s, "AY")); 
          }else
          {
        	  bookInfo.setStatus(0);
        	  bookInfo.setMessage("返回信息为空或不正确："+bookInfoMsg);
          }
          return bookInfo; 
      }  
      /***
       * 解析还书图书信息
       * @param bookInfoMsg 返回的图书SIP2信息
       * @return 图书对象
       * @throws ParseException 
       * @date 2016-8-4 下午5:32:12
       */
      public  CheckOutResponse parseBorrow(String bookInfoMsg) throws ParseException
      { 
          // 示例:
          // 121NNY20160418    115255AO010|AAD7AACEFE|ABB00084|AJ证据法学|AH2017-12-18|AF借阅成功|AY1AZEAA4
          // 120NNN20160418    115331AO010|AAD7AACEFE|ABB000841|AJ|AH2016-04-18|AF本图书不存在|AY1AZEBA4 
    	  CheckOutResponse bookInfo = new CheckOutResponse();
    	  if (!StringEx.isExEmpty(bookInfoMsg) && bookInfoMsg.startsWith("12"))
    	  {
    		  String[] s = bookInfoMsg.split(Const.SVERTICAL);  
    		  //执行状态 0 失败 1 成功
              int status = Integer.parseInt(bookInfoMsg.substring(2, 3));
              bookInfo.setStatus(status); 
	
	          // 必有字段
              bookInfo.setBookId(getFirstField(s, "AB")); // 图书条码或RFID号
              bookInfo.setBookName(getContentByField(s, "AJ")); // 图书题名   
              bookInfo.setNeedReturnDate(getContentByField(s, "AH")); // 还书日期
              bookInfo.setMessage(getContentByField(s, "AF")); //信息 
              if(StringEx.isExEmpty(bookInfo.getMessage()))
            	  bookInfo.setMessage(getContentByField(s, "AG")); //信息 
              bookInfo.setEnd(getContentByField(s, "AY")); 
    	  }else
          {
        	  bookInfo.setStatus(0);
        	  bookInfo.setMessage("返回信息为空或不正确："+bookInfoMsg);
          }
          return bookInfo; 
      } 



      /***
       *  续借图书对象
       * @param bookInfoMsg  返回的图书SIP2信息
       * @param CBookInfo 图书对象
       * @return
       * @throws ParseException 
       * @date 2016-8-5 下午3:16:04
       */
      public  CheckOutResponse parseRenew(String bookInfoMsg) throws ParseException
      { 
          // 示例:
    	  //301YNY20160805    153005AO|AAD7AACEFE|ABB00084|AJ证据法学|AH20180405|BT01|CIN|BHCNY|BV000|CK000|
    	  //                            CH001|BK20160805153005|AF续借成功|AG续借成功|AY1AZDA88
          // 300NNY20160418    115515AO|AA0001942544|ABA0336809|AJ|AH20160418|BT01|CIN|BHCNY|BV000|CK000|
          //                            CH001|BK20160418115515|AF本书已超期|AG本书已超期|AY1AZDBBD
    	  CheckOutResponse bookInfo = new CheckOutResponse();
    	  if (!StringEx.isExEmpty(bookInfoMsg) && bookInfoMsg.startsWith("30"))
    	  {
	    	  String[] s = bookInfoMsg.split(Const.SVERTICAL);  
			  //执行状态 0 失败 1 成功
	          int status = Integer.parseInt(bookInfoMsg.substring(2, 3));
	          bookInfo.setStatus(status); 
	
	          // 必有字段  
              bookInfo.setBookId(getContentByField(s, "AB")); // 图书条码或RFID号
              bookInfo.setBookName(getContentByField(s, "AJ")); // 图书题名   
              bookInfo.setNeedReturnDate(getContentByField(s, "AH")); // 还书日期
              bookInfo.setMessage(getContentByField(s, "AF")); //信息 
              if(StringEx.isExEmpty(bookInfo.getMessage()))
            	  bookInfo.setMessage(getContentByField(s, "AG")); //信息 
              bookInfo.setEnd(getContentByField(s, "AY")); 
              //发生日期
              bookInfo.setOccurDate(getContentByField(s, "BK"));
	
	          //可选字段
	          bookInfo.setFee(getContentByField(s, "BV")); //fee  
	          
	          bookInfo.setEnd(getContentByField(s, "AY")); 
    	  }else
          {
        	  bookInfo.setStatus(0);
        	  bookInfo.setMessage("返回信息为空或不正确："+bookInfoMsg);
          }
          return bookInfo; 
      }  
      
      
      public static void main(String[] agrs)
      {
/*    	  String ip = "192.168.11.176";
    	  int port = 6789;
    	  SocketClient client = SocketClient.connect(ip, port);
    	  client.setCharset("GB2312");
    	  String result = client.sendAndRead(SIP2MsgUitl.renewMsg("D7AACEFE", "", "B00084"));
    	  System.out.println("result:  "+result);
    	  */
    	  
    	  /*try {
    		  System.out.println(DateUtils.parseDate("2018-06-09","yyyy-MM-dd"));
		} catch (ParseException e) { 
			e.printStackTrace();
		} */
    	    //301YNY20160810    154928AO|AAD7AACEFE|ABB00084|AJ证据法学|AH20180410|BT01|CIN|BHCNY|BV000|CK000|CH001|BK20160810154928|AF续借成功|AG续借成功|AY1AZDA76
    	    String dateString = "20160810154928";  
    	    try  
    	    {  
    	  	  System.out.println(DateUtils.parseDate(dateString,"yyyyMMdd"));
    	    }  
    	    catch (ParseException e)  
    	    {  
    	        System.out.println(e.getMessage());  
    	    }  
    	  
      }  

}
